<script setup lang="ts">
import type { PageParam } from '~/types/global'
import type { SysUser } from '~/types/system/user'
import { objectHasContent } from '~/utils'
import { columns } from './columns'
import UserEdit from './components/user-edit.vue'
import UserSearchForm from './components/user-search.vue'

defineOptions({
  // 跟路由name保持一致
  name: 'system_user',
})

const { loading, setLoading } = useLoading(true)
const searchForm = ref()
// 表格数据
const dataSource = ref<SysUser[]>([])
// 表格选中数据的key
const selectedKeys = ref<string[]>([])
// 表格工具栏配置
const defaultToolbar = ref<boolean>(true)// 表格分页器配置
const page = ref({
  total: 0,
  limit: 10,
  current: 1,
})
// 是否显示"新增/编辑"弹窗
const showEdit = ref(false)
// 当前需要编辑的用户
const current = ref<SysUser>()
// 默认分页查询参数
const pageParam: PageParam<SysUser> = { page: 1, limit: 10, sort: 'id', order: 'desc' }

/**
 * 获取表格数据
 * @param param 自定义分页查询参数
 */
async function fetchTableData(param?: PageParam<SysUser>) {
  setLoading(true)
  try {
    // 分页查询
    const { success, data } = await pageUserApi({
      ...pageParam,
      ...param,
    })

    if (!success) return

    // 修改分页器的页码、数据总条数
    if (param && param.page) page.value.current = param.page
    page.value.total = Number(data!.count)
    // 表格数据赋值
    dataSource.value = data!.list as unknown as SysUser[]
  } catch {
  } finally {
    setLoading(false)
  }
}
fetchTableData()

/** 分页事件 */
function changePage(data: any) {
  // 获取搜索组件查询条件
  const formModel = searchForm.value.formModel

  // 自定义分页查询参数
  const param = {
    ...{ model: formModel },
    ...pageParam,
    page: data.current,
    limit: data.limit,
  } as PageParam<SysUser>

  // 获取表格数据
  fetchTableData(param)
}

/** 排序事件 */
function changeSort(data: any) {
  // 获取搜索组件查询条件
  const formModel = searchForm.value.formModel

  // 自定义分页查询参数
  const param = {
    ...{ model: formModel },
    ...{ page: page.value.current, limit: page.value.limit },
    sort: data.prop,
    order: data.order,
  } as PageParam<SysUser>

  // 获取表格数据
  fetchTableData(param)
}

/** 表格多选事件 */
function changeSelection(data: SysUser[] | undefined) {
  if (!data) return

  selectedKeys.value = data.map(item => item.id as string)
}

/** 表单搜索事件 */
function handleSearch(formModel: SysUser) {
  // 自定义分页查询参数
  const param = {
    ...{ model: formModel },
    ...pageParam,
    page: 1,
  } as PageParam<SysUser>

  // 获取表格数据
  fetchTableData(param)
}

/**
 * 打开编辑弹窗
 * @param row 需要编辑的用户数据。可以为空，新增的时候不需要传
 */
function openEditModal(row?: SysUser) {
  current.value = row
  showEdit.value = true
}

/** 处理单体删除 */
function handleDelete(id: string) {
  if (!id) {
    toastWarn('请选择用户')
    return
  }

  confirmMsg('确定要删除这条数据吗？', {}, async () => {
    try {
      // 单体删除
      const { success, message } = await deleteUserApi(id)
      if (!success) {
        toastError(message || '操作失败')
        return
      }

      toastSuccess(message || '操作成功')
      // 重新获取表格数据
      fetchTableData()
    } catch (err) {
      notifyError((err as Error).message, '错误')
    }
  })
}

/** 处理批量删除 */
async function handleBatchDelete() {
  // 参数校验
  const ids = selectedKeys.value
  if (ids.length === 0) {
    toastWarn('请选择用户')
    return
  }

  confirmMsg('确定要删除这些数据吗？', {}, async () => {
    try {
      // 批量删除
      const { success, message } = await batchDeleteUserApi(ids)
      if (!success) {
        toastError(message || '操作失败')
        return
      }

      toastSuccess(message || '操作成功')
      // 重新获取表格数据
      fetchTableData()
    } catch (err) {
      notifyError((err as Error).message, '错误')
    }
  })
}

/** 处理重置密码 注意：重置密码会强制该用户下线，请谨慎操作 */
function handlerResetPwd(id: string) {
  confirmMsg('确定要将该用户的密码重置为\'123456\'吗？', {}, async () => {
    try {
      // 重置用户密码
      const { success, message } = await resetUserPasswordApi({
        id,
        password: '123456',
      })
      if (!success) {
        toastError(message || '操作失败')
        return
      }

      toastSuccess(message || '操作成功')
      // 重新获取表格数据
      fetchTableData()
    } catch (err) {
      notifyError((err as Error).message, '错误')
    }
  })
}

/** 修改用户状态 */
async function handleChangeState(val: number, row: SysUser) {
  // 如果row = {}, return
  if (!objectHasContent(row)) return

  const oldValue = row.state
  try {
    const { success, message } = await updateUserStateApi({ id: row.id as string, state: row.state! })
    if (!success) {
      toastError(message || '修改失败')
      row.state = oldValue
      return
    }
    toastSuccess(message || '修改成功')
    row.state = val
  } catch {
    toastError('请求失败')
    row.state = val
  }
}
</script>

<template>
  <div class="z-container">
    <!-- 表格搜索栏 -->
    <el-card shadow="never">
      <UserSearchForm ref="searchForm" @on-search="handleSearch" />
    </el-card>

    <!-- 数据表格 -->
    <div class="z-table-box">
      <e-table
        :loading="loading"
        :page="page"
        :columns="columns"
        :data-source="dataSource"
        :default-toolbar="defaultToolbar"
        height="480px"
        table-layout="auto"
        @change="changePage"
        @sort-change="changeSort"
        @selection-change="changeSelection"
      >
        <!-- 工具栏 -->
        <template #toolbar>
          <el-button
            v-any-permission="['sys:user:add', 'sys:user:save']"
            type="primary"
            @click="openEditModal()"
          >
            <el-icon><i-ep-plus /></el-icon>
            新增
          </el-button>
          <el-button
            v-permission="'sys:user:delete'"
            type="danger"
            @click="handleBatchDelete"
          >
            <el-icon><i-ep-delete /></el-icon>
            删除
          </el-button>
        </template>

        <!-- 操作列 -->
        <template #operator="{ row }">
          <e-action-group size="small">
            <el-button
              v-any-permission="['sys:user:edit', 'sys:user:update']"
              size="small"
              type="primary"
              @click="openEditModal(row)"
            >
              编辑
            </el-button>
            <el-button
              v-permission="'sys:user:delete'"
              size="small"
              type="danger"
              @click="handleDelete(row.id)"
            >
              删除
            </el-button>
            <!-- 折叠区域 -->
            <template #dropdown>
              <div
                v-any-permission="['sys:user:edit', 'sys:user:update']"
                @click="handlerResetPwd(row.id)"
              >
                重置密码
              </div>
            </template>
          </e-action-group>
        </template>

        <!-- 头像列 -->
        <template #avatar="{ row }">
          <el-avatar :src="row.avatar" />
        </template>

        <!-- 角色列 -->
        <template #roles="{ row }">
          <el-tag v-for="role in row.roles" :key="role.id" type="info" effect="plain">
            {{ role?.name || '无' }}
          </el-tag>
        </template>

        <!-- 性别列 -->
        <template #sex="{ row }">
          <span v-if="row.sex">{{ row.sex === 1 ? '男' : '女' }}</span>
          <span v-else>未知</span>
        </template>

        <!-- 状态列 -->
        <template #state="{ row }">
          <el-switch
            :model-value="row.state"
            inline-prompt
            active-text="启用"
            :active-value="1"
            inactive-text="停用"
            :inactive-value="0"
            :validate-event="false"
            @change="(val: any) => handleChangeState(val as number, row)"
          />
        </template>
      </e-table>
    </div>

    <!-- 弹窗 -->
    <UserEdit v-model:visible="showEdit" :data="current" @done="fetchTableData" />
  </div>
</template>
